package fun.stgoder.test1;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;

public class TestLockSupport {

    public static void main(String[] args) {
        PThread t = new PThread();

        t.start();

        TestUtil.sleepSeconds(5);

        t.pause1();
        t.pause1();

        TestUtil.sleepSeconds(5);

        t.resume1();

        System.out.println("---------------------------");

        f1();
    }

    private static Thread t0, t1;

    public static void f1() {

        List<Integer> list = new ArrayList<>();

        t0 = new Thread(() -> {

            TestUtil.sleepSeconds(1);

            while (list.size() != 5) {
                System.out.println("t0 size != 5, == " + list.size() + ", wait");
                LockSupport.park();
                System.out.println("t0 size == " + list.size() + ", exit");
                LockSupport.unpark(t1);
                break;
            }
        });
        t0.start();

        t1 = new Thread(() -> {

            TestUtil.sleepSeconds(1);

            for (int i = 0; i < 20; i++) {

                list.add(i);
                System.out.println("t1 add " + i);
                if (list.size() == 5) {
                    LockSupport.unpark(t0);
                    LockSupport.park();
                }
            }
        });
        t1.start();


    }
}

class PThread extends Thread {
    private boolean paused = false;

    private Lock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true) {
            while (paused) {
                LockSupport.park();
            }

            // work code
            System.out.println(1);

            TestUtil.sleepSeconds(1);
        }
    }

    public void pause1() {
        lock.lock();
        try {
            paused = true;
        } finally {
            lock.unlock();
        }
    }

    public void resume1() {
        lock.lock();
        try {
            paused = false;
            LockSupport.unpark(this);
        } finally {
            lock.unlock();
        }
    }
}
